﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Just.Library.Util;
using ConsoleHelper = ConsoleAppFramework.Util.ConsoleHelper;

namespace ConsoleApp.Job.TaskFramework
{
    /// <summary>
    /// 任务管理类
    /// </summary>
    public class TaskManager
    {
        private List<ITask> tasks = new List<ITask>();

        public TaskManager(List<ITask> tasks)
        {
            this.tasks.AddRange(tasks);
            foreach (ITask task in tasks)
            {
                task.TaskException += new TaskExceptionHandler(On_TaskException);
                task.TaskLog += new TaskLogHandler(On_TaskLog);
            }
        }

        /// <summary>
        /// 启动任务
        /// </summary>
        public void Start()
        {
            Parallel.ForEach(tasks, task =>
            {
                Thread.CurrentThread.Priority = task.Priority;
                string taskName = task.GetType().Name;
                try
                {
                    //DEBUG true 这句干掉
                    if (!ConfigHelper.GetBool("Debug"))
                    {
                        ConsoleHelper.WriteWarningLine($"{taskName}任务运行于Prod模式下！");

                        //ConsoleHelper.WriteInfoLine($"抖音任务【{taskName}】开启监控");
                        //var cosoleClient = new XiGua.Spider.OnlineService.ConsoleClient(taskName, task.Author, 5, task.MobileTo, task.TaskCount);
                    }
                    else
                    {
                        ConsoleHelper.WriteWarningLine($"{taskName}任务运行于DEBUG模式下！");
                    }
                    task.Execute();

                }
                catch (Exception ex)
                {
                    if (!ConfigHelper.GetBool("Debug"))
                    {
                        //MailHelper.SendMailWithApi(task.MobileTo, $"{taskName}1执行异常", ex.Message);
                    }
                }
            });
        }

        void On_TaskLog(object source, string message, bool persistence = false)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            var task = source as ITask;
            Console.WriteLine("***** [" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "] " + task.Remark + "  *****\r\n" + message + "\r\n");
            if (persistence)
            {
                LogHelper.WriteCustom(message, "Tasks\\" + task.Remark + "\\");
            }
        }

        void On_TaskException(object source, Exception exception, string message, bool persistence = false)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(source.GetType().ToString() + ":" + message);
            Console.WriteLine(exception.Message);
            Console.WriteLine("");
            if (persistence)
            {
                LogHelper.WriteException(source.GetType().ToString() + ":" + message, exception);

            }
        }
    }

    public class TaskStarter
    {
        /// <summary>
        /// 初始化任务列表
        /// </summary>
        /// <returns></returns>
        public static List<ITask> Init()
        {
            List<ITask> lstTask = new List<ITask>();

            if (ConfigHelper.GetBool("Debug", false))
            {
                var types = Assembly.GetAssembly(typeof(TaskBase)).GetTypes();
                foreach (var item in types)
                {
                    if (item.IsInterface)
                        continue;

                    var isDefined = item.IsDefined(typeof(DebuggerAttribute), false);
                    if (isDefined)
                    {
                        ITask task = (ITask)Activator.CreateInstance(item);
                        task.Priority = ThreadPriority.Highest;
                        task.Remark = task.GetType().Name ?? "Debug";
                        lstTask.Add(task);
                    }
                }
            }
            else
            {
                var doc = XElement.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskConfig.config"));
                var elements = doc.Elements("Task");
                foreach (var item in elements)
                {
                    if (item.Attribute("Enable").Value == "1")
                    {
                        ITask task = (ITask)Activator.CreateInstance(Type.GetType(item.Attribute("Starter").Value));
                        task.Priority = (ThreadPriority)Enum.Parse(typeof(ThreadPriority), item.Attribute("Priority").Value);
                        task.Remark = item.Attribute("Remark").Value;
                        lstTask.Add(task);
                    }
                }
            }

            return lstTask;
        }
        public static List<ITask> Init(string remark, string starter, string priority, string taskCount = "1")
        {
            List<ITask> lstTask = new List<ITask>();
            ITask task = (ITask)Activator.CreateInstance(Type.GetType(starter));
            task.Priority = (ThreadPriority)Enum.Parse(typeof(ThreadPriority), priority);
            task.Remark = remark;
            task.TaskCount = Just.Library.Extensions.StringExtensions.ToInt32(taskCount, 1);
            lstTask.Add(task);
            return lstTask;
        }
    }
}
